/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.tnmk.worktime.utils;

import java.util.ArrayList;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;

/**
 *
 * @author tnmkhoi
 */
public class TimePeriodUtils {

  public static List<DateTime> getLastestWeekBeginTimesFrom(DateTime dateTime, int numWeeks) {
    List<DateTime> rs = new ArrayList<>(numWeeks);
    DateTime iWeekBeginTime = withTimeAtStartOfWeek(dateTime);
    rs.add(iWeekBeginTime);
    for (int i = 1; i < numWeeks; i++) {
      iWeekBeginTime = iWeekBeginTime.minusDays(7);
      rs.add(iWeekBeginTime);
    }
    return rs;
  }

  public static List<DateTime> getLastestMonthBeginTimesFrom(DateTime dateTime, int numWeeks) {
    List<DateTime> rs = new ArrayList<>(numWeeks);
    DateTime iWeekBeginTime = withTimeAtStartOfMonth(dateTime);
    rs.add(iWeekBeginTime);
    for (int i = 1; i < numWeeks; i++) {
      iWeekBeginTime = iWeekBeginTime.minusDays(1);
      iWeekBeginTime = withTimeAtStartOfMonth(iWeekBeginTime);
      rs.add(iWeekBeginTime);
    }
    return rs;
  }

  public static DateTime withTimeAtEndOfDay(DateTime dateTime) {
    return dateTime.withTime(23, 59, 59, 999);
  }

  /**
   * @param dateTime
   * @return the time at first second of MONDAY
   */
  public static DateTime withTimeAtStartOfWeek(DateTime dateTime) {
    DateTime rs = dateTime.withDayOfWeek(DateTimeConstants.MONDAY);
    rs = rs.withTimeAtStartOfDay();
    return rs;
  }

  public static DateTime withTimeAtStartOfMonth(DateTime dateTime) {
    DateTime rs = dateTime.withDayOfMonth(1);
    rs = rs.withTimeAtStartOfDay();
    return rs;
  }

  /**
   * @param dateTime
   * @return the time at last second of SUNDAY
   */
  public static DateTime withTimeAtEndOfWeek(DateTime dateTime) {
    DateTime rs = dateTime.withDayOfWeek(DateTimeConstants.SUNDAY);
    rs = withTimeAtEndOfDay(rs);
    return rs;
  }

  /**
   * @param dateTime
   * @return the time at last second of SUNDAY
   */
  public static DateTime withTimeAtEndOfMonth(DateTime dateTime) {
    DateTime nextMonth = dateTime.plusMonths(1);
    DateTime beginOfNextMonth = nextMonth.withDayOfMonth(1);
    DateTime endOfMonth = beginOfNextMonth.minusDays(1);
    DateTime rs = withTimeAtEndOfDay(endOfMonth);
    return rs;
  }

  public static boolean isInSameWeek(DateTime dtA, DateTime dtB) {
    int weekA = dtA.getWeekOfWeekyear();
    int yearA = dtA.getYear();

    int weekB = dtB.getWeekOfWeekyear();
    int yearB = dtB.getYear();
    return weekA == weekB && yearA == yearB;
  }

  public static boolean isInSameMonth(DateTime dtA, DateTime dtB) {
    int monthA = dtA.getMonthOfYear();
    int yearA = dtA.getYear();

    int monthB = dtB.getMonthOfYear();
    int yearB = dtB.getYear();
    return monthA == monthB && yearA == yearB;
  }

  /**
   * Begin of a week is Monday
   *
   * @param time
   * @return
   */
  public static boolean isInThisWeek(DateTime dateTime) {
    DateTime now = DateTime.now();
    int week = now.getWeekOfWeekyear();
    int year = now.getYear();

    int targetWeek = dateTime.getWeekOfWeekyear();
    int targetYear = dateTime.getYear();
    return week == targetWeek && year == targetYear;
  }

  /**
   * Begin of a week is Monday
   *
   * @param time
   * @return
   */
  public static boolean isInThisMonth(DateTime dateTime) {
    DateTime now = DateTime.now();
    int month = now.getMonthOfYear();
    int year = now.getYear();

    int targetMonth = dateTime.getMonthOfYear();
    int targetYear = dateTime.getYear();
    return month == targetMonth && year == targetYear;
  }

}
